part of '../time.dart';

abstract class TimeCounter {
  /// 当前时刻，可能为负
  Duration get time;
  bool get isRunning;

  /// 当前时刻为起点，向前或者向后计时
  void forward();
  void backward();

  /// 停在特定的某个地方，或者在当前时刻停止
  stop({Duration? at});

  factory TimeCounter() => _TimeCounter();
}

class _TimeCounter implements TimeCounter {
  /// 累计值
  /// 每当Timer停止，就把数据存到这里
  Duration _accumulation = Duration.zero;

  /// 锚
  /// 1. 每当开始运行时，会将锚设置为当前时间
  /// 2. 只要读取时间差，就知道运行了多久
  /// 3. 如果加上[accumulation]，就是总时间
  ///
  /// anchor为空时，就是计时器停止的时候
  /// 如果anchor有值，就是计时器运行的时候
  DateTime? _anchor;
  bool _isForward = true;

  /// 核心公式：时间=累计值+差值
  /// 差值会根据向前还是向后运行有所不同
  @override
  Duration get time {
    if (_anchor != null) {
      final delta = DateTime.now().difference(_anchor!);
      return _accumulation + (delta * (_isForward ? 1 : -1));
    }
    return _accumulation;
  }

  @override
  bool get isRunning => _anchor != null;

  @override
  void forward() => _start(forward: true);

  @override
  void backward() => _start(forward: false);

  void _start({required bool forward}) {
    // 如果正在运行，则先在当下停止
    if (isRunning) stop();
    // 确定接下来运行的方向
    _isForward = forward;
    // 将当前时间定为锚点
    _anchor = DateTime.now();
  }

  @override
  void stop({Duration? at}) {
    _accumulation = at ?? time;
    _anchor = null;
  }
}
